(function closure() {
    for (var i = 0; i < 5; i++) {
        setTimeout(function () {
            console.log("before fix：" + i);//需要注意的是这里定时器回调函数被调用的是发生在这个for循环结束之后，所以那个时候得到的i全部都等于5；所以会打印出5个5
        }, i * 1000);
    }
})();
// 虽然在这里定义了五个函数，在五个时间点调用，每个函数都有闭包，但是要注意的是，这五个函数公用的是同一个作用域，所以他们取到的i也是同一个i

// 所以为了解决这个问题，关键就在于要给五个回调函数不同的作用域。因此可以用到之前说的IIFE
(function closureAfterFix() {
    for (var i = 0; i < 6; i++) {
        (function (j) {
            setTimeout(function () {
                console.log("after fix: " + j)
            }, j * 1000);
        })(i)
    }
})();


// 下面这种是不行的，虽然有自己的字面作用域，但是字面作用域是空，还是要到外层去寻找
/* for (var i=1; i<=5; i++) {
    (function(){
        setTimeout( function timer(){
            console.log( i );
		}, i*1000 );
	})();
} */

(function () {
    for (var i = 1; i <= 5; i++) {
        let j = i; // 使用let来构造块作用域也可以解决这个问题
        setTimeout(function timer() {
            console.log(j);
        }, j * 1000);
    }
})();

(function name() {
    for (let i = 0; i < 5; i++) {
        console.log(i);//i会在每一个循环中都声明一遍
        setTimeout(function timer() {
            console.log(i);
        }, i * 1000);
    }
})();